package il.ac.biu.cs.grossmm.api.simple;

/**
 * Represents a subscription state, as defined in RFC's 3265 and 3857.
 * Subscription state are essentially states of a suscription FSM defined in RFC
 * 3857:
 * 
 * <pre>
 *  
 *           subscribe,
 *        policy=       +----------+
 *        reject        |          |&lt;------------------------+
 *        +------------&gt;|terminated|&lt;---------+              |
 *        |             |          |          |              |
 *        |             |          |          |noresource    |
 *        |             +----------+          |rejected      |
 *        |                  &circ;noresource      |deactivated   |
 *        |                  |rejected        |probation     |
 *        |                  |deactivated     |timeout       |noresource
 *        |                  |probation       |              |rejected
 *        |                  |giveup          |              |giveup
 *        |                  |                |              |approved
 *     +-------+         +-------+        +-------+          |
 *     |       |subscribe|       |approved|       |          |
 *     | init  |--------&gt;|pending|-------&gt;|active |          |
 *     |       |no policy|       |        |       |          |
 *     |       |         |       |        |       |          |
 *     +-------+         +-------+        +-------+          |
 *        |                  |                &circ;              |
 *        | subscribe,       |                |              |
 *        +-----------------------------------+              |
 *          policy = accept  |            +-------+          |
 *                           |            |       |          |
 *                           |            |waiting|----------+
 *                           +-----------&gt;|       |
 *                            timeout     |       |
 *                                        +-------+
 *  
 * </pre>
 * 
 */
public enum SubscriptionState {
	/**
	 * Initial state: when a SUBSCRIBE request arrives, the subscription FSM is
	 * created in the <tt>INIT</tt> state. This state is transient.
	 */
	INIT,

	/**
	 * If the "Subscription-State" header value is "active", it means that the
	 * subscription has been accepted and (in general) has been authorized. If
	 * there is existing policy that determines that the subscription is
	 * authorized, the FSM moves into the active state. This state indicates
	 * that the subscriber will receive notifications.
	 */
	ACTIVE,
	/**
	 * If the "Subscription-State" value is "pending", the subscription has been
	 * received by the notifier, but there is insufficient policy information to
	 * grant or deny the subscription yet.
	 * 
	 * If, when a subscription arrives, there is no authorization policy in
	 * existence, the subscription moves into the pending state. In this state,
	 * the server is awaiting an authorization decision. No notifications are
	 * generated on changes in presence state (an initial NOTIFY will have been
	 * delivered as per RFC 3265 [1]), but the subscription FSM is maintained.
	 * If the authorization decision comes back positive, the subscription is
	 * approved, and moves into the active state. If the authorization is
	 * negative, the subscription is rejected, and the FSM goes into the
	 * terminated state. It is possible that the authorization decision can take
	 * a very long time. In fact, no authorization decision may arrive until
	 * after the subscription itself expires. If a pending subscription suffers
	 * a timeout, it moves into the waiting state. At any time, the server can
	 * decide to end a pending or waiting subscription because it is concerned
	 * about allocating memory and CPU resources to unauthorized subscription
	 * state. If this happens, a "giveup" event is generated by the server,
	 * moving the subscription to terminated.
	 */
	PENDING,

	/**
	 * The waiting state is similar to pending, in that no notifications are
	 * generated. However, if the subscription is approved or denied, the FSM
	 * enters the terminated state, and is destroyed. Furthermore, if another
	 * subscription is received to the same resource, from the same watcher, for
	 * the same event package, event package parameters and filter in the body
	 * of the SUBSCRIBE request (if one was present initially), the FSM enters
	 * the terminated state with a "giveup" event, and is destroyed. This
	 * transition occurs because, on arrival of a new subscription with
	 * identical parameters, it will enter the pending state, making the waiting
	 * state for the prior subscription redundant. The purpose of the waiting
	 * state is so that a user can
	 * 
	 * fetch watcherinfo state at any time, and learn of any subscriptions that
	 * arrived previously (and which may arrive again) which require an
	 * authorization decision. Consider an example. A subscribes to B. B has not
	 * defined policy about this subscription, so it moves into the pending
	 * state. B is not "online", so that B's software agent cannot be contacted
	 * to approve the subscription. The subscription expires. Let's say it were
	 * destroyed. B logs in, and fetches its watcherinfo state. There is no
	 * record of the subscription from A, so no policy decision is made about
	 * subscriptions from A. B logs off. A refreshes its subscription. Once
	 * more, the subscription is pending since no policy is defined for it. This
	 * process could continue indefinitely. The waiting state ensures that B can
	 * find out about this subscription attempt.
	 */
	WAITING,

	/**
	 * If the "Subscription-State" value is "terminated", the subscriber should
	 * consider the subscription terminated. A subscription can be terminated at
	 * any time because the resource associated with that subscription no longer
	 * exists. This corresponds to the noresource event.
	 */
	TERMINATED;
}
